home *** CD-ROM | disk | FTP | other *** search
- /* This is part of libio/iostream, providing -*- C++ -*- input/output.
- Copyright (C) 1993 Free Software Foundation
-
- This file is part of the GNU IO Library. This library is free
- software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- As a special exception, if you link this library with files
- compiled with a GNU compiler to produce an executable, this does not cause
- the resulting executable to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License. */
-
- /* Written by Per Bothner (bothner@cygnus.com). */
-
- #include "libioP.h"
- #include "streambuf.h"
-
- // The ANSI draft requires that operations on cin/cout/cerr can be
- // mixed with operations on stdin/stdout/stderr on a character by
- // character basis. This normally requires that the streambuf's
- // used by cin/cout/cerr be stdiostreams. However, if the stdio
- // implementation is the one that is built using this library,
- // then we don't need to, since in that case stdin/stdout/stderr
- // are identical to &__std_filebuf_0/&__std_filebuf_1/&__std_filebuf_2.
-
- #if 1 //def _STDIO_USES_IOSTREAM
- #define USE_FILEBUF
- #endif
-
- #if _G_NAMES_HAVE_UNDERSCORE
- #define UNDERSCORE "_"
- #else
- #define UNDERSCORE ""
- #endif
-
- #ifdef USE_FILEBUF
- #if 1
- #include "libio.h"
- #define CIN_SBUF _IO_stdin_
- #define COUT_SBUF _IO_stdout_
- #define CERR_SBUF _IO_stderr_
- #else
- #define CIN_SBUF __std_filebuf_0
- #define COUT_SBUF __std_filebuf_1
- #define CERR_SBUF __std_filebuf_2
- #endif
- static int use_stdiobuf = 0;
- #else
- #define CIN_SBUF __stdin_stdiobuf
- #define COUT_SBUF __stdout_stdiobuf
- #define CERR_SBUF __stderr_stdiobuf
- static int use_stdiobuf = 1;
- #endif
-
- #if 1
- struct _fake_filebuf;
- extern _fake_filebuf __std_filebuf_0, __std_filebuf_1, __std_filebuf_2;
- #endif
- struct _fake_stdiobuf;
- extern _fake_stdiobuf __stdin_stdiobuf, __stdout_stdiobuf, __stderr_stdiobuf;
-
- #define cin CIN
- #define cout COUT
- #define cerr CERR
- #define clog CLOG
- #include "iostream.h"
- #undef cin
- #undef cout
- #undef cerr
- #undef clog
-
- #ifdef __GNUG__
- #define PAD 0 /* g++ allows 0-length arrays. */
- #else
- #define PAD 1
- #endif
- struct _fake_istream {
- struct myfields {
- #ifdef __GNUC__
- _ios_fields *vb; /* pointer to virtual base class ios */
- _IO_ssize_t _gcount;
- #else
- /* This is supposedly correct for cfront. */
- _IO_ssize_t _gcount;
- void *vptr;
- _ios_fields *vb; /* pointer to virtual base class ios */
- #endif
- } mine;
- _ios_fields base;
- char filler[sizeof(struct istream)-sizeof(struct _ios_fields)+PAD];
- };
- struct _fake_ostream {
- struct myfields {
- #ifndef __GNUC__
- void *vptr;
- #endif
- _ios_fields *vb; /* pointer to virtual base class ios */
- } mine;
- _ios_fields base;
- char filler[sizeof(struct ostream)-sizeof(struct _ios_fields)+PAD];
- };
-
- #define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
- (streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
-
- #ifdef __GNUC__
- #define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
- _fake_ostream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
- #define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
- _fake_istream NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
- #else
- #define OSTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
- _fake_ostream NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
- #define ISTREAM_DEF(NAME, SBUF, TIE, EXTRA_FLAGS) \
- _fake_ostream NAME = {{0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS)}};
- #endif
-
- OSTREAM_DEF(cout, COUT_SBUF, NULL, 0)
- OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf)
- ISTREAM_DEF(cin, CIN_SBUF, (ostream*)&cout, 0)
-
- /* Only for (partial) compatibility with AT&T's library. */
- OSTREAM_DEF(clog, CERR_SBUF, (ostream*)&cout, 0)
-
- // Switches between using __std_filebuf_{0,1,2} and
- // __std{in,out,err}_stdiobuf for standard streams. This is
- // normally not needed, but is provided for AT&T compatibility.
-
- int ios::sync_with_stdio(int new_state)
- {
- #ifdef TODO
- #ifdef _STDIO_USES_IOSTREAM
- // It is always synced.
- return 0;
- #else
- if (new_state == use_stdiobuf) // The usual case now.
- return use_stdiobuf;
- if (new_state) {
- cout.base._strbuf = (streambuf*)&__stdout_stdiobuf;
- cin.base._strbuf = (streambuf*)&__stdin_stdiobuf;
- cerr.base._strbuf = (streambuf*)&__stderr_stdiobuf;
- clog.base._strbuf = (streambuf*)&__stderr_stdiobuf;
- } else {
- cout.base._strbuf = (streambuf*)&__std_filebuf_1;
- cin.base._strbuf = (streambuf*)&__std_filebuf_0;
- cerr.base._strbuf = (streambuf*)&__std_filebuf_2;
- clog.base._strbuf = (streambuf*)&__std_filebuf_2;
- }
- int old_state = use_stdiobuf;
- use_stdiobuf = new_state;
- return old_state;
- #endif
- #endif
- return 0;
- }
-